import React, { useMemo } from 'react';
import { Box, Cylinder, Sphere, RoundedBox, Plane } from '@react-three/drei';
import * as THREE from 'three';

const MapEnvironment = ({ 
  showObstacles = true, 
  showBoundaries = true, 
  showTerrain = true,
  mapSize = 50 
}) => {
  // Generate random building positions
  const buildings = useMemo(() => {
    const buildingArray = [];
    const numBuildings = 12;
    
    for (let i = 0; i < numBuildings; i++) {
      const x = (Math.random() - 0.5) * (mapSize * 0.6);
      const z = (Math.random() - 0.5) * (mapSize * 0.6);
      const height = Math.random() * 8 + 3;
      const width = Math.random() * 3 + 2;
      const depth = Math.random() * 3 + 2;
      const type = Math.floor(Math.random() * 3); // 0: office, 1: residential, 2: industrial
      
      buildingArray.push({
        id: i,
        position: [x, height / 2, z],
        size: [width, height, depth],
        type,
        color: type === 0 ? '#34495e' : type === 1 ? '#e67e22' : '#95a5a6'
      });
    }
    
    return buildingArray;
  }, [mapSize]);

  // Generate terrain features
  const terrainFeatures = useMemo(() => {
    const features = [];
    const numFeatures = 8;
    
    for (let i = 0; i < numFeatures; i++) {
      const x = (Math.random() - 0.5) * (mapSize * 0.8);
      const z = (Math.random() - 0.5) * (mapSize * 0.8);
      const radius = Math.random() * 2 + 1;
      const height = Math.random() * 1.5 + 0.5;
      
      features.push({
        id: i,
        position: [x, height / 2, z],
        radius,
        height,
        type: Math.random() > 0.5 ? 'hill' : 'rock'
      });
    }
    
    return features;
  }, [mapSize]);

  // Generate trees
  const trees = useMemo(() => {
    const treeArray = [];
    const numTrees = 20;
    
    for (let i = 0; i < numTrees; i++) {
      const x = (Math.random() - 0.5) * (mapSize * 0.9);
      const z = (Math.random() - 0.5) * (mapSize * 0.9);
      const height = Math.random() * 4 + 3;
      const trunkRadius = 0.1 + Math.random() * 0.1;
      const crownRadius = 0.8 + Math.random() * 0.5;
      
      treeArray.push({
        id: i,
        position: [x, 0, z],
        height,
        trunkRadius,
        crownRadius
      });
    }
    
    return treeArray;
  }, [mapSize]);

  return (
    <group>
      {/* Ground Plane */}
      <Plane 
        args={[mapSize * 2, mapSize * 2]} 
        rotation={[-Math.PI / 2, 0, 0]} 
        position={[0, -0.01, 0]}
        receiveShadow
      >
        <meshStandardMaterial 
          color="#2d5a27" 
          roughness={0.8}
          metalness={0.1}
        />
      </Plane>

      {/* Boundary Walls */}
      {showBoundaries && (
        <group>
          {/* North Wall */}
          <RoundedBox 
            args={[mapSize, 3, 0.5]} 
            radius={0.1} 
            smoothness={4} 
            position={[0, 1.5, mapSize / 2]}
            castShadow
            receiveShadow
          >
            <meshStandardMaterial 
              color="#7f8c8d" 
              metalness={0.2}
              roughness={0.7}
            />
          </RoundedBox>

          {/* South Wall */}
          <RoundedBox 
            args={[mapSize, 3, 0.5]} 
            radius={0.1} 
            smoothness={4} 
            position={[0, 1.5, -mapSize / 2]}
            castShadow
            receiveShadow
          >
            <meshStandardMaterial 
              color="#7f8c8d" 
              metalness={0.2}
              roughness={0.7}
            />
          </RoundedBox>

          {/* East Wall */}
          <RoundedBox 
            args={[0.5, 3, mapSize]} 
            radius={0.1} 
            smoothness={4} 
            position={[mapSize / 2, 1.5, 0]}
            castShadow
            receiveShadow
          >
            <meshStandardMaterial 
              color="#7f8c8d" 
              metalness={0.2}
              roughness={0.7}
            />
          </RoundedBox>

          {/* West Wall */}
          <RoundedBox 
            args={[0.5, 3, mapSize]} 
            radius={0.1} 
            smoothness={4} 
            position={[-mapSize / 2, 1.5, 0]}
            castShadow
            receiveShadow
          >
            <meshStandardMaterial 
              color="#7f8c8d" 
              metalness={0.2}
              roughness={0.7}
            />
          </RoundedBox>

          {/* Corner Posts */}
          {[
            [mapSize / 2, mapSize / 2],
            [mapSize / 2, -mapSize / 2],
            [-mapSize / 2, mapSize / 2],
            [-mapSize / 2, -mapSize / 2]
          ].map(([x, z], index) => (
            <Cylinder 
              key={`corner-${index}`}
              args={[0.3, 0.3, 4]} 
              position={[x, 2, z]}
              castShadow
              receiveShadow
            >
              <meshStandardMaterial 
                color="#34495e" 
                metalness={0.4}
                roughness={0.6}
              />
            </Cylinder>
          ))}
        </group>
      )}

      {/* Buildings */}
      {showObstacles && buildings.map((building) => (
        <group key={`building-${building.id}`}>
          {/* Main building structure */}
          <RoundedBox 
            args={building.size} 
            radius={0.1} 
            smoothness={4} 
            position={building.position}
            castShadow
            receiveShadow
          >
            <meshStandardMaterial 
              color={building.color} 
              metalness={building.type === 2 ? 0.6 : 0.1}
              roughness={building.type === 1 ? 0.8 : 0.4}
            />
          </RoundedBox>

          {/* Building details based on type */}
          {building.type === 0 && ( // Office building
            <>
              {/* Windows */}
              {Array.from({ length: Math.floor(building.size[1] / 1.5) }, (_, floor) => (
                <group key={`floor-${floor}`}>
                  {Array.from({ length: 3 }, (_, window) => (
                    <Box 
                      key={`window-${window}`}
                      args={[0.3, 0.4, 0.02]} 
                      position={[
                        building.position[0] + (window - 1) * 0.5,
                        building.position[1] - building.size[1] / 2 + (floor + 0.5) * 1.5,
                        building.position[2] + building.size[2] / 2 + 0.01
                      ]}
                    >
                      <meshStandardMaterial 
                        color="#87CEEB" 
                        transparent 
                        opacity={0.7}
                        metalness={0.1}
                        roughness={0.1}
                      />
                    </Box>
                  ))}
                </group>
              ))}
            </>
          )}

          {building.type === 1 && ( // Residential building
            <>
              {/* Roof */}
              <Box 
                args={[building.size[0] + 0.2, 0.3, building.size[2] + 0.2]} 
                position={[
                  building.position[0],
                  building.position[1] + building.size[1] / 2 + 0.15,
                  building.position[2]
                ]}
                castShadow
              >
                <meshStandardMaterial 
                  color="#8B4513" 
                  roughness={0.9}
                  metalness={0.0}
                />
              </Box>
            </>
          )}

          {building.type === 2 && ( // Industrial building
            <>
              {/* Smokestacks */}
              <Cylinder 
                args={[0.2, 0.2, 3]} 
                position={[
                  building.position[0] + building.size[0] / 3,
                  building.position[1] + building.size[1] / 2 + 1.5,
                  building.position[2]
                ]}
                castShadow
              >
                <meshStandardMaterial 
                  color="#2c3e50" 
                  metalness={0.7}
                  roughness={0.3}
                />
              </Cylinder>
            </>
          )}
        </group>
      ))}

      {/* Trees */}
      {showObstacles && trees.map((tree) => (
        <group key={`tree-${tree.id}`} position={tree.position}>
          {/* Trunk */}
          <Cylinder 
            args={[tree.trunkRadius, tree.trunkRadius, tree.height]} 
            position={[0, tree.height / 2, 0]}
            castShadow
            receiveShadow
          >
            <meshStandardMaterial 
              color="#8B4513" 
              roughness={0.9}
              metalness={0.0}
            />
          </Cylinder>

          {/* Crown */}
          <Sphere 
            args={[tree.crownRadius]} 
            position={[0, tree.height + tree.crownRadius * 0.5, 0]}
            castShadow
            receiveShadow
          >
            <meshStandardMaterial 
              color="#228B22" 
              roughness={0.8}
              metalness={0.0}
            />
          </Sphere>
        </group>
      ))}

      {/* Terrain Features */}
      {showTerrain && terrainFeatures.map((feature) => (
        <group key={`terrain-${feature.id}`}>
          {feature.type === 'hill' ? (
            <Sphere 
              args={[feature.radius]} 
              position={feature.position}
              castShadow
              receiveShadow
            >
              <meshStandardMaterial 
                color="#8FBC8F" 
                roughness={0.9}
                metalness={0.0}
              />
            </Sphere>
          ) : (
            <Box 
              args={[feature.radius * 1.5, feature.height, feature.radius * 1.2]} 
              position={feature.position}
              rotation={[0, Math.random() * Math.PI, 0]}
              castShadow
              receiveShadow
            >
              <meshStandardMaterial 
                color="#696969" 
                roughness={0.8}
                metalness={0.1}
              />
            </Box>
          )}
        </group>
      ))}
    </group>
  );
};

export default MapEnvironment;
